package com.iwhalecloud.bss.kite.cucc.order.accept.constructor;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.iwhalecloud.bss.kite.cucc.order.loader.InstLoaderFactory;
import com.iwhalecloud.bss.kite.cucc.order.util.AcceptUtils;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.IInst;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.OfferInst;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.ProdInst;
import com.iwhalecloud.bss.kite.dataservice.entity.order.OrderItemChange;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.change.KiteInstChange;
import com.iwhalecloud.bss.kite.manager.inst.change.KiteRelChange;
import com.iwhalecloud.bss.kite.manager.inst.graph.impl.RelEdge;
import com.iwhalecloud.bss.kite.manager.util.ManagerUtils;
import com.iwhalecloud.bss.kite.manager.util.RelTypeUtils;
import com.iwhalecloud.bss.kite.order.client.dto.InstContainer;
import com.iwhalecloud.bss.kite.order.client.dto.OrderRequest;
import com.ztesoft.bss.common.util.SpringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 数据构造器管理器
 */
public abstract class DataConstructorManager {

    /**
     * 构造订单请求对象
     * @param orderRequest
     * @param instChanges
     * @param relChanges
     */
    public static void buildOrderRequest(OrderRequest orderRequest, List<KiteInstChange> instChanges,
        List<KiteRelChange> relChanges) {
        if (CollectionUtils.isEmpty(instChanges) && CollectionUtils.isEmpty(relChanges)) {
            return;
        }

        Map<String, List<KiteInstChange>> instChangeMap = ManagerUtils.toInstChangeMap(instChanges);
        Map<String, List<KiteRelChange>> relChangeMap = ManagerUtils.toRelChangeMap(relChanges);

        orderRequest.setInstChangeMap(instChangeMap);
        orderRequest.setRelChangeMap(relChangeMap);

        Maps.newHashMap(instChangeMap).forEach((key, instChangeList) -> {
            if (CollectionUtils.isEmpty(instChangeList)) {
                return;
            }

            InstType instType = instChangeList.get(0).getSubInstType();
            String instId = instChangeList.get(0).getSubInstId();

            IDataConstructor<String, IInst> dataConstructor = DataConstructorFactory.getInstConstructor(instType);
            if (!dataConstructor.contains(orderRequest, "", instId, null)) {
                dataConstructor.build(orderRequest, instId, null);
            }
        });

        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        Maps.newHashMap(relChangeMap).forEach((key, relChangeList) -> {
            if (CollectionUtils.isEmpty(relChangeList)) {
                return;
            }

            Lists.newArrayList(relChangeList).forEach(relChange -> {
                // 包含基础销售品实例的关系变动都是后来添加的，不处理
                if (Objects.equals(InstType.BASE_OFFER_INST, relChange.getSourceInstType())
                    || Objects.equals(InstType.BASE_OFFER_INST, relChange.getTargetInstType())) {
                    return;
                }
                // 账户级的关系变动
                if (Objects.equals(InstType.OFFER_INST_ACCT, relChange.getTargetInstType())) {
                    return;
                }

                IDataConstructor<String, IInst> sourceDataConstructor = DataConstructorFactory
                    .getInstConstructor(relChange.getSourceInstType());
                if (!sourceDataConstructor.contains(orderRequest, "", relChange.getSourceInstId(), null)) {
                    sourceDataConstructor.build(orderRequest, relChange.getSourceInstId(),
                        ImmutableMap.of(KiteInst.ACTION_TYPE, ActionType.M.name()));
                }
                else {
                    handleParentActionType(orderRequest, relChange.getSourceInstType(), relChange.getSourceInstId());
                }

                IDataConstructor<String, IInst> targetDataConstructor = DataConstructorFactory
                    .getInstConstructor(relChange.getTargetInstType());
                if (!targetDataConstructor.contains(orderRequest, "", relChange.getTargetInstId(), null)) {
                    targetDataConstructor.build(orderRequest, relChange.getTargetInstId(), null);
                }

                if (Objects.equals(RelType.PROD_REL_TYPE_100600, relChange.getRelType())) {
                    // 接入产品实例和功能产品实例的关系不生成ProdInstRel
                    return;
                }

                RelEdge relEdge = querySceneInstService.getInstRel(orderRequest.getCustId(),
                    relChange.getSourceInstType(), relChange.getSourceInstId(), relChange.getTargetInstType(),
                    relChange.getTargetInstId(), relChange.getRelType());
                IDataConstructor<RelEdge, IInst> dataConstructor = DataConstructorFactory
                    .getRelConstructor(relChange.getRelType().getType());
                if (Objects.nonNull(dataConstructor)) {
                    if (!dataConstructor.contains(orderRequest, relChange.getSourceInstId(),
                        relChange.getTargetInstId(),
                        ImmutableMap.of(IDataConstructor.KEY_REL_TYPE, RelTypeUtils.getRelTypeCode(relEdge)))) {
                        dataConstructor.build(orderRequest, relEdge, null);
                    }
                }
            });
        });
    }

    /**
     * 把上级销售品实例的actionType改为M
     * @param orderRequest
     * @param instType
     * @param instId
     */
    public static void handleParentActionType(OrderRequest orderRequest, InstType instType, String instId) {
        if (!ObjectUtils.allNotNull(orderRequest, instType) || StringUtils.isBlank(instId)) {
            return;
        }

        OfferInst offerInst = null;
        if (Objects.equals(InstType.PROD_INST, instType)) {
            ProdInst prodInst = InstContainer.ofRequest(orderRequest).getProdInst(instId);
            if (Objects.nonNull(prodInst)) {
                offerInst = InstContainer.ofRequest(orderRequest).getOfferInst(prodInst.getCompInstId());
            }
        }
        else if (AcceptUtils.isOfferInst(instType)) {
            offerInst = InstContainer.ofRequest(orderRequest).getOfferInst(instId);
        }

        if (Objects.nonNull(offerInst)
            && StringUtils.equalsAny(offerInst.getActionType(), ActionType.A.name(), ActionType.K.name())) {
            AcceptUtils.setActionType(offerInst, ActionType.M.name());
        }
    }

    /**
     * Description: <br>
     * 根据订单变动信息构造
     * @author xiao.xuzhang<br>
     * @taskId <br>
     * @param orderRequest
     * @param orderItemChanges <br>
     */
    public static void buildInstData(OrderRequest orderRequest, List<OrderItemChange> orderItemChanges) {
        for (OrderItemChange orderItemChange : orderItemChanges) {
            String tableName = orderItemChange.getTableName();
            String instId = orderItemChange.getInstId();
            String custId = orderItemChange.getCustId();
            InstLoaderFactory.getInstLoader(tableName).loadInst(orderRequest, tableName, instId, custId);

            // 根据订单变动信息还原实例值
            IInst inst = InstContainer.ofRequest(orderRequest).getInst(tableName, instId);
            AcceptUtils.inverse(orderItemChange, inst);
        }
    }
}
